﻿using System;
using System.Net.NetworkInformation;
using System.Threading;
using RayDen.Library.Components.SystemComponents;
using RayDen.RayEngine.Core.Devices;
using RayDen.RayEngine.Core.Interface;
using RayDen.RayEngine.Corrector.Samplers;
using RayDen.RayEngine.Corrector.Types;
using RayDen.RayEngine.Managers;

namespace RayDen.RayEngine.Corrector.Renderers
{
    public class CorrectorRenderer : ICorrectorRenderer
    {
        public bool PreprocessRequired;
        protected string stats;

        private FrameConfiguration currentFrame;

        protected LightsourceSampler LightsourceSampler;
        protected BsdfSampler BsdfSampler;
        protected ImagePlaneSampler ImagePlaneSampler;

        protected ImagePlaneSample[] Samples;
        protected CorrectorImageFilm film;

        public CorrectorRenderer(FrameConfiguration currentFrame, CorrectorImageFilm film)
        {
            this.film = film;
            this.currentFrame = currentFrame;
            this.ImagePlaneSampler = new RandomImagePlaneSampler(currentFrame.Width, currentFrame.Height);
            this.LightsourceSampler = new LightsourceSampler(currentFrame.Scene);
            this.GenerateImageSamples();
        }


        public void GenerateImageSamples()
        {
            Tracer.TraceLine("Generate image samples [screen per thread]");
            this.Samples = new ImagePlaneSample[currentFrame.Width * currentFrame.Height];
            for (int i = 0; i < currentFrame.Width * currentFrame.Height; i++)
            {
                this.Samples[i] = this.ImagePlaneSampler.GetSample(i);
            }
            Tracer.TraceLine("Generate image samples done.");

        }

        public CorrectorRenderThread[] CreateThreads(int threadCount, IIntersectionEngine intersectionEngine, FrameManager fm)
        {
            var threads = new CorrectorRenderThread[threadCount];
            for (int i = 0; i < threadCount; i++)
            {
                threads[i] = new CorrectorRenderThread(i, intersectionEngine, currentFrame.Scene, currentFrame.LowLatency, film, new GlobalSamplingContext()
                {
                    BsdfSampler = this.BsdfSampler,
                    LightSampler = this.LightsourceSampler,
                    PrimarySpaceSampler = this.CreatePrimarySampler(currentFrame.Width, currentFrame.Height, i)
                }, fm);

                threads[i].SetSamples(this.Samples);
            }
            return threads;
        }

        public virtual IPrimarySpaceSampler CreatePrimarySampler(int width, int heigh, int index)
        {
            return new UniformPrimarySampler(index);
        }



        public string GetEngineStats()
        {
            return stats;
        }
    }
}